import React from 'react'
import {connectComponent} from '../../../store/utils'
import {bindErrorActions, ErrorActionsType} from '../../../store/action/error'
import {Loading} from '../../../ui/loading/Loading'
import {CONSTANTS} from '../../../../constants'
import {apiPost} from '../../../api'
import {Button} from '../../../ui/button/Button'
import {LSKeys, LSMethods} from '../../../storage'
import {AuthActionsType, bindAuthActions} from '../../../store/action/auth'
import ButtonIcon from '../../../ui/icon/ButtonIcon'
import {mdiClose, mdiMinus, mdiPlus} from '@mdi/js'
import Divider from '../../../ui/common/Divider'
import {COLORS} from '../../../ui/color'
import {round} from '../../../utils'
import {KEYS} from '../../../storage/keys'
import {CartDto} from '../../../../api/CartDto'

export interface CartContainerProps {
  cart: CartDto
  authActions: AuthActionsType
  errorActions: ErrorActionsType
}

const CartContainer: React.FC<CartContainerProps> = ({
  cart,
  authActions,
  errorActions,
}): React.ReactElement => {
  const writeOrder = async (): Promise<void> => {
    const token: any = LSMethods.getStorageData(KEYS.TOKEN)
    const url = CONSTANTS.apiUrl + '/order/write'
    const res = await apiPost(url, {token: token}, {})
    if (res.success) {
      authActions.setState({
        cart: {
          dishes: [],
          id: undefined,
        } as CartDto,
      })
      window.location.replace(CONSTANTS.webUrl + '/order-history')
    }
  }

  const writeInCart = async (
    newId: string,
    isRemove: boolean = false,
    isDelete: boolean = false,
    isAllDelete: boolean = false,
  ): Promise<void> => {
    const token = LSMethods.getStorageData(LSKeys.TOKEN)

    let newDishes = cart.dishes
    if (isAllDelete) {
      newDishes = []
    } else {
      let index = newDishes.findIndex((nd) => nd.id === newId)
      if (index !== -1) {
        if (isRemove || isDelete) {
          if (newDishes[index].count > 1 && !isDelete) {
            newDishes[index].count = newDishes[index].count - 1
          } else {
            newDishes.splice(index, 1)
          }
        } else {
          newDishes[index].count = newDishes[index].count + 1
        }
      } else {
        newDishes.push({
          id: newId,
          count: 1,
        })
      }
    }
    await apiPost(
      CONSTANTS.apiUrl + '/cart/write',
      {
        token: token,
        dishes: newDishes,
      },
      {},
    )
    authActions.setState({
      cart: {
        dishes: newDishes,
        id: cart?.id || undefined,
      } as CartDto,
    })
  }

  const renderCartList = (): React.ReactNode => {
    let items: React.ReactNode[] = []
    if ((cart?.dishes || []).length === 0) {
      return (
        <div className={'d-flex flex-column w-100 align-items-center'}>
          <p className={'empty-p mb-x6'}>Корзина пуста</p>
        </div>
      )
    }

    for (let item of cart?.dishes || []) {
      items.push(
        <div key={item.id} className={'cart-list-item'}>
          <img
            className={'cart-list-item-img'}
            src={item.img ? `${CONSTANTS.apiUrl}/image/${item.id}` : '/buffet/img/bg_img.jpg'}
            alt={'Изображение блюда'}
          />
          <div className={'cart-list-item-body'}>
            <div className={'d-flex flex-column'}>
              <p className={'cart-list-item-name'}>{item.dishname}</p>
              <p className={'cart-list-item-description'}>цена {item.price} &#8381; / 1 шт</p>
            </div>
            <div className={'d-flex flex-row align-items-center justify-content-between'}>
              <div className={'d-flex flex-row align-items-center'}>
                <ButtonIcon
                  iconPath={mdiMinus}
                  title={''}
                  className={'mr-x4'}
                  isHoverArea
                  onClick={async (): Promise<void> => {
                    await writeInCart(item.id, true)
                  }}
                />
                <span className={'text-fs-16-24'}>{item.count}</span>
                <ButtonIcon
                  iconPath={mdiPlus}
                  title={''}
                  className={'ml-x4'}
                  isHoverArea
                  onClick={async (): Promise<void> => {
                    await writeInCart(item.id, false)
                  }}
                />
              </div>
              <span className={'cart-list-item-price'}>
                {round(item.price * item.count)} &#8381;
              </span>
            </div>
            <div className={'cart-list-item-delete'}>
              <ButtonIcon
                iconPath={mdiClose}
                title={''}
                className={''}
                isHoverArea
                size={'sm'}
                hoverIconColor={'danger'}
                color={COLORS.red}
                onClick={async (): Promise<void> => {
                  await writeInCart(item.id, true, true)
                }}
              />
            </div>
          </div>
        </div>,
      )
    }

    return <div>{items}</div>
  }

  if (cart) {
    let priceTotal: number = 0
    if (cart?.dishes?.length > 0) {
      for (let dish of cart?.dishes) {
        priceTotal += dish.price * dish.count
      }
    }

    return (
      <div className={'cart-wrapper'}>
        {renderCartList()}
        <Divider className={'w-100 mb-x4 mt-x2'} />
        <div className={'d-flex flex-row justify-content-between mb-x4'}>
          <span className={'text-fs-16-24'}>Итого: </span>
          <span className={'cart-price-total'}>{round(priceTotal)} &#8381;</span>
        </div>
        <div className={'d-flex flex-row'}>
          <Button
            type={'button'}
            onClick={async (): Promise<void> => {
              await writeOrder()
            }}
            size={'md'}
            disabled={!cart || (cart.dishes || []).length === 0}
            className={'mb-0 w-100 mr-x2'}>
            {cart?.id ? 'Сохранить' : 'Заказать'}
          </Button>
          <Button
            type={'button'}
            onClick={async (): Promise<void> => {
              await writeInCart(undefined, false, false, true)
            }}
            size={'md'}
            style={'outline'}
            disabled={!cart || (cart.dishes || []).length === 0}
            className={'mb-0 w-100 ml-x2'}>
            Очистить
          </Button>
        </div>
      </div>
    )
  } else {
    return <Loading />
  }
}

export default connectComponent(
  (state, props) => ({
    user: state.auth.user,
    cart: state.auth.cart,
  }),
  (dispatch) => ({
    authActions: bindAuthActions(dispatch),
    errorActions: bindErrorActions(dispatch),
  }),
  CartContainer,
)
